home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / libs / knowhow4 / bgi_font.cpp < prev    next >
C/C++ Source or Header  |  1994-11-16  |  6KB  |  228 lines

  1. #include "bgi_font.h"
  2.  
  3. #include <string.h>
  4. #include <fcntl.h>
  5. #include <io.h>
  6. #include <STDDEF.H>
  7. #include <alloc.h>
  8.  
  9. #define MAXFILESIZE 16000
  10.  
  11. char* BGI_Font::buffer = NULL;
  12.  
  13. BGI_Font::BGI_Font(char* fileName)
  14.     {
  15.     h_just = 0; // LEFT_TEXT
  16.     v_just = 0; // BOTTOM_TEXT
  17.     if(buffer != NULL)
  18.     {
  19.     delete buffer;
  20.     buffer = NULL;
  21.     }
  22.     multx = multy = divx = divy = 1;
  23.     polypoints = NULL;
  24.     if(fileName == NULL)
  25.     return;
  26.     load(fileName);
  27.     polypoints = new int[256];  // Default number of points in closed
  28.     };
  29. //////////////
  30. BGI_Font::~BGI_Font()
  31.     {
  32.     delete[] buffer;
  33.     buffer = NULL;
  34.     delete polypoints;
  35.     }
  36. ////////////////
  37. void BGI_Font::load(char* fileName)
  38.     {
  39.     int handle;
  40.     if((handle = open(fileName, O_RDONLY | O_BINARY)) == -1)
  41.     {
  42.     kh_error_code = KH_FILE_ERROR;
  43.     return;
  44.     }
  45.     if(buffer == NULL)
  46.     if((buffer = new char[MAXFILESIZE]) == NULL)
  47.         {
  48.         close(handle);
  49.         kh_error_code = KH_MEMORY_ERROR;
  50.         return;
  51.         }
  52.  
  53.     if(read(handle, buffer, MAXFILESIZE) == -1)
  54.     {
  55.     delete buffer;
  56.     close(handle);
  57.     kh_error_code = KH_FILE_ERROR;
  58.     return;
  59.     }
  60.     close(handle);
  61.  
  62.     int pos = 0;
  63.     while(buffer[pos] != 26)                 // All info fields are skipped
  64.     pos++;
  65.     pos++;
  66.     // BGI_Font Font Info
  67.     HeaderSize = ((int*)(buffer + pos))[0];           // ...
  68.     pos += sizeof(int);
  69.     pos += 4;                 // char* FontName;
  70.     FontSize = ((int*)(buffer + pos))[0];           // ...
  71.     pos += sizeof(int);       // int FontSize, Font without header
  72.     pos++;                    // char FontVersion, > 0
  73.     pos++;                    // char FontModification;
  74.     pos += sizeof(int);       // int  BGI_FontInfo, BGI_Font version
  75.     // BGI_Font Font descriptor
  76.     while(buffer[pos] != '+')
  77.     pos++;                    // char DscSignature, Always '+'
  78.     pos++;
  79.     SymbolsInFont = buffer[pos++];      // Usually start from ' '
  80.     pos++; pos++;
  81.     FirstSymbol = buffer[pos++];        // Usually start from ' '
  82.     StrokesOffset = ((int*)(buffer + pos))[0]; // Characters descriptions offset
  83.     pos += sizeof(int);
  84.     FillFlag = buffer[pos++];           // Fill or not, default 0
  85.     CapitalHeight = buffer[pos++];      // ...
  86.     BaseLine = buffer[pos++];           // Usually 0
  87.     Descender = buffer[pos++];          // for y, g and other
  88.     pos += 5;                           // char Stub02[5], Not used and set to 0
  89.  
  90.     // BGI_Font Tables
  91.     OffsetTable = (int*)(buffer + pos);     // Offsets of symbols descriptions
  92.     pos += SymbolsInFont * 2;
  93.     WidthTable = (buffer + pos);
  94.     pos += SymbolsInFont;
  95.     vectors = buffer + pos;
  96.     }
  97. ////////////////
  98. int BGI_Font::draw_char(int x, int y, uchar c, int dir)
  99.     {
  100.     if(c >= SymbolsInFont + FirstSymbol || c < FirstSymbol)  // ERROR !!!
  101.     {                                                    // Out of inter-
  102.     kh_error_code = KH_BGI_ERROR;                        // val
  103.     return 0;
  104.     }
  105.     char* pos = vectors + OffsetTable[c - FirstSymbol];  // Find description
  106.     int numpoint = 0;
  107.     moveto(x, y);
  108.     int xpos; int sign; int ypos;
  109.  
  110.     for(int i = 0; (pos [i] & 128); i += 2)              // While end of char
  111.     {                                                // description
  112.     if(!dir)
  113.         {
  114.         xpos = x + (pos [i] & 127) * multx / divx;   // Calculate coords.
  115.         sign = pos[i + 1] & 64 ? 1 : 0;
  116.         ypos = y + (sign * 64 - (pos [i + 1] & 63)) * multy / divy;
  117.         }
  118.     else
  119.         {
  120.         sign = pos[i + 1] & 64 ? 1 : 0;
  121.         xpos = x + (sign * 64 - (pos [i + 1] & 63)) * multx / divx;   // Calculate coords.
  122.         ypos = y - (pos [i] & 127) * multy / divy;
  123.         }
  124.     if((pos [i + 1] & 128) && (pos [i] & 128))  // Drawing via moveto
  125.         {                                       // and lineto
  126.         if(FillFlag)                            // For filled fonts lineto
  127.         {                                   // draws filled part of
  128.         polypoints[numpoint++] = xpos;      // character, like upper
  129.         polypoints[numpoint++] = ypos;      // '.' in ':'
  130.         }                                   // Moveto begin next part
  131.         else                                    // of char.
  132.         lineto(xpos, ypos);
  133.         }
  134.     else
  135.         {
  136.         if(FillFlag && numpoint)
  137.         {
  138.         numpoint = numpoint / 2;
  139.         fillpoly(numpoint, polypoints);
  140.         numpoint = 0;
  141.         }
  142.         else
  143.         moveto(xpos, ypos);
  144.         }
  145.     }
  146.     if(FillFlag && numpoint)                // If next part of char was not
  147.     {                                   // shown.
  148.     numpoint = numpoint / 2;
  149.     fillpoly(numpoint, polypoints);
  150.     numpoint = 0;
  151.     }
  152.  
  153.     return (int)((long)WidthTable[c - FirstSymbol] * multx / divx);
  154.     }
  155. ////////////////
  156. int BGI_Font::outtextxy(int x, int y, uchar far*  str, int dir)
  157.     {
  158.     int len = 0;
  159.     int i = 0;
  160.     int w;
  161.     int h = v_just * getheight() / 2;
  162.     while(str[i])
  163.     switch(h_just)
  164.         {
  165.         case 1: w = gettextwidth(str);
  166.         if(!dir)
  167.             len += draw_char(x - w/2 + len, y + h, str[i++]);
  168.         else
  169.             len += draw_char(x + h, y + w/2 - len, str[i++], dir);
  170.         break;
  171.         case 2: w = gettextwidth(str);
  172.         if(!dir)
  173.             len += draw_char(x - w + len, y + h, str[i++]);
  174.         else
  175.             len += draw_char(x + h, y + w - len, str[i++], dir);
  176.         break;
  177.         case 0:
  178.         default:
  179.         if(!dir)
  180.             len += draw_char(x + len, y + h, str[i++]);
  181.         else
  182.             len += draw_char(x + h, y - len, str[i++], dir);
  183.         break;
  184.         }
  185.     return len;
  186.     }
  187. ////////////////////
  188. int BGI_Font::gettextwidth(uchar far*  str)
  189.     {
  190.     int len = 0;
  191.     int i = 0;
  192.     while(str[i])
  193.     {
  194.     len += WidthTable[str[i] - FirstSymbol];
  195.     i++;
  196.     }
  197.     return len;
  198.     }
  199.  
  200. /*
  201. // Demo for BGI, DOS, Draw nothing, using ABS_GRAF functions.
  202. // See BGIPAINT for the working example.
  203. void main()
  204.     {
  205.     int gdriver = DETECT, gmode;
  206.     initgraph(&gdriver, &gmode, "");
  207.     BGI_Font bgi("bold.chr");
  208.     setcolor(LIGHTGREEN);
  209.     bgi.draw_char(100, 200, 'J', 1);
  210.     bgi.draw_char(100, 200, 'J', 0);
  211.     for(int c = 0; c < 255; c++)
  212.     {
  213.     setfillstyle(SOLID_FILL, RED);
  214.     bar(0,0,getmaxx(),getmaxy());
  215.     setfillstyle(SOLID_FILL, BLUE);
  216.     bgi.setusercharsize(1,1,1,1);
  217.     bgi.draw_char(50, 300, c);
  218.     bgi.setusercharsize(2,1,2,1);
  219.     bgi.draw_char(150, 300, c);
  220.     bgi.setusercharsize(3,1,5,1);
  221.     bgi.draw_char(300, 300, c);
  222.     bgi.setusercharsize(5,1,5,2);
  223.     bgi.draw_char(500, 300, c);
  224.     }
  225.  
  226.     closegraph();
  227.     }
  228. */